let songIndex = 0;
let songsToDelete = [];
let playlistToRemove = "";
let deleteAll = false;
let db;

// Cached DOM elements
const returnToMainFrameButton = document.getElementById('return-to-main-frame');
const addPlaylistButton = document.getElementById('add-new-playlist-button');
const deleteAllButton = document.getElementById('delete-all-button');
const saveButton = document.getElementById('save-button');
const exportButton = document.getElementById('export-button');
const openImportMenuButton = document.getElementById('open-import-menu-button');
const inputPlaylistName = document.getElementById('input-playlist-name');
const playlistsContainer = document.getElementById('playlists');
const songContainer = document.getElementById('songs');
const optionsButton = document.getElementById("options-button");
const playerSelect = document.getElementById("player-select");
const themeSelect = document.getElementById("theme-select");
const fontSelect = document.getElementById("font-select");
const styleSelect = document.getElementById("style-select");
const saveOptionsButton = document.getElementById('save-button-options-panel');
const closeOptionsButton = document.getElementById('close-button-options-panel');
const importButton = document.getElementById("import-button");
const closeImportButton = document.getElementById("close-import-menu");

// Add event listeners
returnToMainFrameButton.addEventListener('click', ReturnToMainFrame);
addPlaylistButton.addEventListener('click', CreateNewPlaylist);
deleteAllButton.addEventListener('click', MarkTotalDeletion);
saveButton.addEventListener('click', SaveChangesToPlaylist);
exportButton.addEventListener('click', ExportDatabaseToFile);
openImportMenuButton.addEventListener('click', OpenImportMenu);
optionsButton.addEventListener('click', OpenOptionMenu);
playerSelect.addEventListener('change', ChangePlayer);
themeSelect.addEventListener('change', ChangeTheme);
fontSelect.addEventListener('change', ChangeFont);
styleSelect.addEventListener('change', ChangeStyle);
saveOptionsButton.addEventListener('click', SaveOptionsPanel);
closeOptionsButton.addEventListener('click', CloseOptionsPanel);
importButton.addEventListener('click', ImportData);
closeImportButton.addEventListener('click', CloseImportPanel);

Initialize();

// Load user preferences
function Initialize() {
    ConnectDatabase().then((db) => {
        songsToDelete = [];
        playlistToRemove = "";
        deleteAll = false;

        // Load preferred player
        RetrieveDataFromDatabase('preferredPlayer').then((preferredPlayer) => {
            if (preferredPlayer !== null && preferredPlayer !== undefined) {
                // Set player
                playerSelect.value = preferredPlayer;
            } else {
                // Set default player
                playerSelect.value = "youtube-player";
            }
        })
        .catch((error) => {
            console.error('Error:', error);
        });

        // Load preferred theme
        RetrieveDataFromDatabase('preferredTheme').then((preferredTheme) => {
            if (preferredTheme !== null && preferredTheme !== undefined) {
                // Set theme
                themeSelect.value = preferredTheme;
                ChangeTheme();
            } else {
                // Set default theme
                themeSelect.value = "white-theme";
                ChangeTheme();
            }
        })
        .catch((error) => {
            console.error('Error:', error);
        });

        // Load preferred font
        RetrieveDataFromDatabase('preferredFont').then((preferredFont) => {
            if (preferredFont !== null && preferredFont !== undefined) {
                // Set font
                fontSelect.value = preferredFont;
                ChangeFont();
            } else {
                // Set default font
                fontSelect.value = "barlow-font";
                ChangeFont();
            }
        })
        .catch((error) => {
            console.error('Error:', error);
        });

        // Load preferred style
        RetrieveDataFromDatabase('preferredStyle').then((preferredStyle) => {
            if (preferredStyle !== null && preferredStyle !== undefined) {
                // Set style
                styleSelect.value = preferredStyle;
                ChangeStyle();
            } else {
                // Set default style
                styleSelect.value = "sharp-style";
                ChangeStyle();
            }
        })
        .catch((error) => {
            console.error('Error:', error);
        });

        LoadPlaylists();

        // Remove text from input field
        const inputInsertBackup = document.getElementById('input-insert-backup');
        inputInsertBackup.value = '';
    })
    .catch((error) => {
        // Connection error
    });
}

// Function to load playlists from localStorage
function LoadPlaylists() {
    GetPlaylistsFromDatabase().then((savedPlaylists) => {
        if (savedPlaylists !== null && savedPlaylists !== undefined) {
            savedPlaylists.playlists.forEach(function (playlist) {
                AddPlaylist(playlist.playlistId, playlist.name);
            });
            localStorage.setItem("savedPlaylists", JSON.stringify(savedPlaylists));
        }
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Function to create a new playlist
function CreateNewPlaylist() {
    GetPlaylistsFromDatabase().then((savedPlaylists) => {
        if (savedPlaylists !== null && savedPlaylists !== undefined) {
            const newRandomId = GenerateRandomId();
            const newPlaylist = {
                "playlistId": newRandomId,
                "name": "New Playlist",
                "songs": []
            };

            savedPlaylists.playlists.push(newPlaylist);
            savedPlaylistsString = JSON.stringify(savedPlaylists);
            // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
            localStorage.setItem("savedPlaylists", savedPlaylistsString);
            // Save to database
            AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
                AddPlaylist(newRandomId, "New Playlist");
            })
            .catch((error) => {
                console.error('Error:', error);
            });
        }
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Function to add a playlist to the UI
function AddPlaylist(id, name) {
    const playlistContainer = document.createElement('div');
    playlistContainer.className = 'playlist';
    playlistContainer.classList.add('playlist', 'list-objects-theme', 'borders-theme');

    const playlistName = document.createElement('div');
    playlistName.classList.add('playlist-name', 'text-theme', 'font-type');
    playlistName.textContent = name || 'New Playlist';

    const playButton = document.createElement('button');
    playButton.classList.add('playlist-play-button', 'borders-theme');
    playButton.addEventListener('click', () => {PlaySongs(id);});


    const editButton = document.createElement('button');
    editButton.classList.add('playlist-edit-button', 'borders-theme');
    editButton.addEventListener('click', () => {ToggleEditPlaylist(id);});

    playlistContainer.appendChild(playlistName);
    playlistContainer.appendChild(playButton);
    playlistContainer.appendChild(editButton);

    playlistsContainer.appendChild(playlistContainer);
}

// Function to toggle between edit and main frames
function ToggleEditPlaylist(playlistId) {
    const playlistMainFrame = document.getElementById('playlist-main-window');
    const editMainFrame = document.getElementById('edit-playlist-main-window');

    editMainFrame.style.display = 'flex';
    playlistMainFrame.style.display = 'none';

    LoadSongs(playlistId);
    ModifyAddSongButton(playlistId);
    ModifyEditPlaylistName(playlistId);
    ModifyInputPlaylistName(playlistId);
    ModifyDeletePlaylistButton(playlistId);

    const inputInsertURL = document.getElementById("input-insert-url");
    inputInsertURL.value = "";
    inputInsertURL.addEventListener("keyup", function(event) {
        if (event.key === "Enter") {
            AddSong(playlistId);
            inputInsertURL.value = "";
        }
    });

    const inputPlaylistName = document.getElementById('input-playlist-name');
    // Load the name of a playlist
    GetPlaylistsFromDatabase().then((savedPlaylists) => {
        if (savedPlaylists !== null && savedPlaylists !== undefined) {
            const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);
            inputPlaylistName.value = playlist ? playlist.name : "";
        }
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}

function GetPlaylistsFromDatabase() {
    return new Promise((resolve, reject) => {
        RetrieveDataFromDatabase('savedPlaylists')
            .then((value) => {
                if (value === null || value === undefined) {
                    CreateNewLocalStorageStructure();
                    const newStructure = {"playlists": []};
                    return newStructure;
                } else {
                    resolve(JSON.parse(value));
                }
            })
            .catch((error) => {
                console.error('Error:', error);
                reject(error);
            });
    });
}

// Function to remove all playlists from the UI
function DestroyPlaylists() {
    const playlistElements = document.querySelectorAll(".playlist");
    playlistElements.forEach(playlist => {
        playlist.remove();
    });
}

// Function to create a new localStorage structure
function CreateNewLocalStorageStructure() {
    const newStructure = {
        "playlists": []
    };

    AddOrUpdateDataInDatabase('savedPlaylists', JSON.stringify(newStructure)).then(() => {
        return;
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Function to load songs for a playlist
function LoadSongs(playlistId) {
    GetPlaylistsFromDatabase().then((savedPlaylists) => {
        if (savedPlaylists !== null && savedPlaylists !== undefined) {
            const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);

            if (playlist) {
                songIndex = 0;
                playlist.songs.forEach(function (song) {
                    songIndex += 1;
                    AddSongElement(song.songId, song.name, playlistId);
                });
            }
        }
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Function to add a song element to the UI
function AddSongElement(songId, name, playlistId) {
    const songContainer = document.createElement('div');
    songContainer.classList.add('song', 'list-objects-theme', 'borders-theme');

    const songNumber = document.createElement('div');
    songNumber.classList.add('song-number', 'text-theme', 'borders-theme', 'font-type');
    songNumber.textContent = songIndex;

    const inputSongName = document.createElement("input");
    inputSongName.classList.add('input-song-name', 'text-theme', 'font-type');
    inputSongName.setAttribute("type", "text");
    inputSongName.setAttribute("value", name);
    inputSongName.setAttribute("disabled", "true");
    inputSongName.addEventListener("keydown", (event) => {
        if (event.key === "Enter") {
            event.preventDefault();
            inputSongName.setAttribute("disabled", "true");
            inputSongName.setSelectionRange(0, 0);
            inputSongName.focus();
            ChangeSongName(playlistId, songId, inputSongName.value);
        }
    });

    const editSongNameButton = document.createElement('button');
    editSongNameButton.classList.add('edit-song-name-button', 'borders-theme');
    editSongNameButton.addEventListener('click', function () {
        ToggleEditSongName(playlistId, songId, inputSongName);
    });

    const removeSongButton = document.createElement('button');
    removeSongButton.classList.add('remove-song-button', 'borders-theme');
    removeSongButton.addEventListener('click', function () {
        ToggleSongDeletion(songContainer, playlistId, songId);
    });

    songContainer.appendChild(songNumber);
    songContainer.appendChild(inputSongName);
    songContainer.appendChild(editSongNameButton);
    songContainer.appendChild(removeSongButton);

    const songParent = document.getElementById('songs');
    songParent.appendChild(songContainer);
}

// Function to toggle editing of song name
function ToggleEditSongName(playlistId, songId, inputSongName) {
    if (inputSongName.disabled) {
        inputSongName.removeAttribute("disabled");
    } else {
        inputSongName.setAttribute("disabled", "true");
        inputSongName.setSelectionRange(0, 0);
        inputSongName.focus();
        ChangeSongName(playlistId, songId, inputSongName.value);
    }
}

// Function to toggle song deletion
function ToggleSongDeletion(songContainer, playlistId, songId) {
    const updatedArray = songsToDelete.filter(innerArray => !innerArray.includes(songId));

    if (updatedArray.length === songsToDelete.length) {
        const songToRemove = [playlistId, songId];
        songsToDelete.push(songToRemove);
        songContainer.classList.add('marked-for-deletion');
    } else {
        songsToDelete = updatedArray;
        songContainer.classList.remove('marked-for-deletion');
    }
}

// Function to modify the "add-song-button" button
function ModifyAddSongButton(playlistId) {
    const addSongButton = document.getElementById('add-song-button');
    addSongButton.addEventListener('click', function () {
        AddSong(playlistId);
        const inputField = document.getElementById("input-insert-url");
        inputField.value = "";
    });
}

// Function to modify the "playlist-change-name-button" button
function ModifyEditPlaylistName(playlistId) {
    const editPlaylistNameButton = document.getElementById('playlist-change-name-button');
    const inputPlaylistName = document.getElementById('input-playlist-name');
    editPlaylistNameButton.addEventListener('click', function () {
        ToggleEditPlaylistName(playlistId, inputPlaylistName);
    });
}

// Function to toggle editing of playlist name
function ToggleEditPlaylistName(playlistId, inputPlaylistName) {
    if (inputPlaylistName.disabled) {
        inputPlaylistName.removeAttribute("disabled");
    } else {
        inputPlaylistName.setAttribute("disabled", "true");
        inputPlaylistName.setSelectionRange(0, 0);
        inputPlaylistName.focus();
        RenamePlaylist(playlistId, inputPlaylistName.value);
    }
}

// Function to remove all events from the "playlist-change-name-button" button
function RemoveAllEventsFromEditPlaylistNameButton() {
    const renamePlaylistButton = document.getElementById("playlist-change-name-button");
    const newButton = renamePlaylistButton.cloneNode(true);
    renamePlaylistButton.parentNode.replaceChild(newButton, renamePlaylistButton);
}

// Function to remove all events from the input playlist name field
function RemoveAllEventsFromInputPlaylistName() {
    const inputPlaylistName = document.getElementById("input-playlist-name");
    const newInput = inputPlaylistName.cloneNode(true);
    inputPlaylistName.parentNode.replaceChild(newInput, inputPlaylistName);
}

// Function to rename a playlist
function RenamePlaylist(playlistId, newName) {
    GetPlaylistsFromDatabase().then((savedPlaylists) => {
        if (savedPlaylists !== null && savedPlaylists !== undefined) {
            const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);

            if (playlist) {
                playlist.name = newName;
            }

            savedPlaylistsString = JSON.stringify(savedPlaylists);
            // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
            localStorage.setItem("savedPlaylists", savedPlaylistsString);
            // Save to database
            AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
                return;
            })
            .catch((error) => {
                console.error('Error:', error);
            });
        }
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Function to remove all events from the "add-song-button" button
function RemoveAllEventsFromAddSongButton() {
    const addSongButton = document.getElementById("add-song-button");
    const newButton = addSongButton.cloneNode(true);
    addSongButton.parentNode.replaceChild(newButton, addSongButton);
}

// Function to remove all events from the "playlist-delete-button" button
function RemoveAllEventsFromPlaylistDeleteButton() {
    const deletePlaylistButton = document.getElementById("playlist-delete-button");
    const newButton = deletePlaylistButton.cloneNode(true);
    deletePlaylistButton.parentNode.replaceChild(newButton, deletePlaylistButton);

    // Remove playlist to be deleted in case there is one and change the field color
    playlistToRemove = "";
    const parent = document.getElementById('playlist-name-parent');
    parent.classList.remove('marked-for-deletion');
}

// Mark all playlists for deletion
function MarkTotalDeletion() {
    if(deleteAll) {
        deleteAll = false;
        // Change button color
        deleteAllButton.classList.remove('total-delete');
    } else {
        deleteAll = true;
        // Change button color
        deleteAllButton.classList.add('total-delete');
    }
}

// Function to add a song to a playlist
function AddSong(playlistId) {
    const inputURL = ExtractVideoId(document.getElementById("input-insert-url").value);

    if (inputURL) {
        GetPlaylistsFromDatabase().then((savedPlaylists) => {
            if (savedPlaylists !== null && savedPlaylists !== undefined) {
                const newRandomId = GenerateRandomId();
                const newSong = {
                    "songId": newRandomId,
                    "name": "New Song",
                    "url": inputURL
                };

                const playlistToUpdate = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);
                playlistToUpdate.songs.push(newSong);

                savedPlaylistsString = JSON.stringify(savedPlaylists);
                // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
                localStorage.setItem("savedPlaylists", savedPlaylistsString);
                // Save to database
                AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
                    songIndex += 1;
                    AddSongElement(newRandomId, "New Song", playlistId);
                })
                .catch((error) => {
                    console.error('Error:', error);
                });
            }
        })
        .catch((error) => {
            console.error('Error:', error);
        });
    }
}

// Function to remove all song elements from the UI
function DestroyAllSongs() {
    const songElements = document.querySelectorAll(".song");
    songElements.forEach(song => {
        song.remove();
    });
}

// Function to generate a random ID
function GenerateRandomId() {
    const timestamp = new Date().getTime();
    const random = Math.random().toString(36).substring(2, 10);
    return `${timestamp}_${random}`;
}

// Function to save changes to playlists
function SaveChangesToPlaylist() {
    if (playlistToRemove !== "") {
        GetPlaylistsFromDatabase().then((savedPlaylists) => {
            if (savedPlaylists !== null && savedPlaylists !== undefined) {
                // Filter out the playlist with the specified ID
                const updatedPlaylists = savedPlaylists.playlists.filter(playlist => playlist.playlistId !== playlistToRemove);

                // Update the JSON data with the filtered playlists
                savedPlaylists.playlists = updatedPlaylists;

                playlistToRemove = "";

                savedPlaylistsString = JSON.stringify(savedPlaylists);
                // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
                localStorage.setItem("savedPlaylists", savedPlaylistsString);
                // Save to database
                AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
                    ReturnToMainFrame();
                })
                .catch((error) => {
                    console.error('Error:', error);
                });
            }
        })
        .catch((error) => {
            console.error('Error:', error);
        });
    }

    if (songsToDelete.length > 0) {
        GetPlaylistsFromDatabase().then((savedPlaylists) => {
            if (savedPlaylists !== null && savedPlaylists !== undefined) {
                let playlistIdToFind = "";

                for (const item of songsToDelete) {
                    playlistIdToFind = item[0];
                    const songIdToRemove = item[1];

                    const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistIdToFind);

                    if (playlist) {
                        playlist.songs = playlist.songs.filter(song => song.songId !== songIdToRemove);
                        const index = savedPlaylists.playlists.findIndex(p => p.playlistId === playlistIdToFind);
                        if (index !== -1) {
                            savedPlaylists.playlists[index] = playlist;
                        }
                    }
                }
                songsToDelete = [];

                savedPlaylistsString = JSON.stringify(savedPlaylists);
                // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
                localStorage.setItem("savedPlaylists", savedPlaylistsString);
                // Save to database
                AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
                    DestroyAllSongs();
                    LoadSongs(playlistIdToFind);
                })
                .catch((error) => {
                    console.error('Error:', error);
                });
            }
        })
        .catch((error) => {
            console.error('Error:', error);
        });
    }
}

// Function to change the name of a song
function ChangeSongName(playlistId, songId, newName) {
    GetPlaylistsFromDatabase().then((savedPlaylists) => {
        if (savedPlaylists !== null && savedPlaylists !== undefined) {
            const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);

            if (playlist) {
                const song = playlist.songs.find(song => song.songId === songId);

                if (song) {
                    song.name = newName;
                }
            }

            savedPlaylistsString = JSON.stringify(savedPlaylists);
            // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
            localStorage.setItem("savedPlaylists", savedPlaylistsString);
            // Save to database
            AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
                return;
            })
            .catch((error) => {
                console.error('Error:', error);
            });
        }
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Function to play songs in a playlist
function PlaySongs(playlistId) {
    let savedPlaylists = JSON.parse(localStorage.getItem('savedPlaylists'));
    let songUrls = "";
    for (const playlist of savedPlaylists.playlists) {
        if (playlist.playlistId === playlistId) {
            for (const song of playlist.songs) {
                songUrls += song.url + ",";
            }
            break;
        }
    }

    if (songUrls) {
        if(playerSelect.value === 'youtube-player')
        {
            window.open("http://www.youtube.com/watch_videos?video_ids=" + songUrls);
        }
        else
        {
            window.open("http://yewtu.be/watch_videos?video_ids=" + songUrls);
        }
    }
}

// Function to clean up and return to main menu
function ReturnToMainFrame() {
    // Get DOM elements
    const playlistMainFrame = document.getElementById('playlist-main-window');
    const editMainFrame = document.getElementById('edit-playlist-main-window');
    const inputPlaylistName = document.getElementById("input-playlist-name");

    // Disable input playlist name
    inputPlaylistName.setAttribute("disabled", "true");

    // Show the main frame and hide the edit frame
    playlistMainFrame.style.display = 'grid';
    editMainFrame.style.display = 'none';

    // Reset and clean up
    DestroyAllSongs();
    RemoveAllEventsFromAddSongButton();
    RemoveAllEventsFromEditPlaylistNameButton();
    RemoveAllEventsFromInputPlaylistName();
    RemoveAllEventsFromPlaylistDeleteButton();
    songsToDelete = [];
    DestroyPlaylists();
    LoadPlaylists();
}

// Function to close options panel
function CloseOptionsPanel() {
    // Unmark delition
    deleteAll = false;
    // Change button color
    deleteAllButton.classList.remove('total-delete');

    // Reload playlists
    DestroyPlaylists();
    LoadPlaylists();

    // Show main menu
    const playlistMainFrame = document.getElementById('playlist-main-window');
    const optionsMenu = document.getElementById("options-main-window");
    optionsMenu.style.display = 'none';
    playlistMainFrame.style.display = 'grid';
}

// Function to modify input field for playlist name
function ModifyInputPlaylistName(playlistId) {
    const inputPlaylistName = document.getElementById('input-playlist-name');
    inputPlaylistName.addEventListener("keydown", (event) => {
        if (event.key === "Enter") {
            event.preventDefault();
            ToggleEditPlaylistName(playlistId, inputPlaylistName);
        }
    });
}

// Function to modify playlist-delete-button
function ModifyDeletePlaylistButton(playlistId) {
    // Add listener to delete playlist button
    const deletePlaylistButton = document.getElementById('playlist-delete-button');
    deletePlaylistButton.addEventListener('click', function () {
        const parent = document.getElementById('playlist-name-parent');
        if (playlistToRemove !== "") { // There alrady is a playlsit marked for deletion, unmart it
            playlistToRemove = "";
            parent.classList.remove('marked-for-deletion');
        } else { // Mark playlist for deletion
            playlistToRemove = playlistId;
            parent.classList.add('marked-for-deletion');
        }
    });
}

// Export the saved playlists to a json file
function ExportDatabaseToFile() {
    GetPlaylistsFromDatabase().then((jsonData) => {
        if (jsonData !== null && jsonData !== undefined) {
            let data = "";
            jsonData.playlists.forEach((playlist, index) => {
                // Convert the playlistData to a JSON string
                data += JSON.stringify(playlist) + ",";
            });

            data = data.substring(0, data.length -1); // Removes the last extra comma
            data = "[" + data + "]"; // Add [] brackets so it can be parsed back into JSON

            const blob = new Blob([data], { type: 'text/plain' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.style.display = 'none';
            a.href = url;
            a.setAttribute('download', "Playlist");
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Function to assign new playlistId values
function AssignNewPlaylistIds(data) {
    data.playlists.forEach((playlist) => {
        playlist.playlistId = GenerateRandomId();
    });
}

// Change the player
function ChangePlayer() {
    playerName = playerSelect.value;

    // Update database with preferred player
    AddOrUpdateDataInDatabase('preferredPlayer', playerName)
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Change the visual themes
function ChangeTheme() {
    themeName = themeSelect.value;

    // Remove existing theme classes
    const themes = ['white-theme', 'black-theme', 'neon-pink-theme', 'matrix-theme', 'huwhite-theme', 'blue-theme', 'coffee-theme', 'night-theme', 'forest-theme'];
    const body = document.body;
    body.classList.remove(...themes);

    // Add the selected theme class
    body.classList.add(themeName);

    // Update database with preferred theme
    AddOrUpdateDataInDatabase('preferredTheme', themeName)
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Change font
function ChangeFont() {
    fontName = fontSelect.value;

    // Remove existing font classes
    const fonts = ['barlow-font', 'cormorant-unicase-font', 'exo2-font', 'gemunu-libre-font', 'josefin-sans-font', 'oswald-font', 'roboto-condensed-font', 'roboto-font', 'roboto-slab-font', 'space-grotesk-font', 'zilla-slab-font'];
    const body = document.body;
    body.classList.remove(...fonts);

    // Add the selected font class
    body.classList.add(fontName);

    // Update database with preferred font
    AddOrUpdateDataInDatabase('preferredFont', fontName)
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Change style
function ChangeStyle() {
    styleName = styleSelect.value;

    // Remove existing style classes
    const styles = ['sharp-style', 'round-style', 'leviosa-style'];
    const body = document.body;
    body.classList.remove(...styles);

    // Add the selected font class
    body.classList.add(styleName);

    // Update database with preferred style
    AddOrUpdateDataInDatabase('preferredStyle', styleName)
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Function to call the options menu and hide the main frame
function OpenOptionMenu() {
    const playlistMainFrame = document.getElementById('playlist-main-window');
    const optionsMenu = document.getElementById("options-main-window");

    optionsMenu.style.display = 'flex';
    playlistMainFrame.style.display = 'none';
}

// Function to destroy all playlists and return to main manu
function SaveOptionsPanel() {
    if (deleteAll) {
        // Destroy all playlists
        CreateNewLocalStorageStructure();

        // Unmark delition
        deleteAll = false;

        // Change button color
        deleteAllButton.classList.remove('total-delete');
    }
}

// Function that opens a specific menu dedicated to importing new data
function OpenImportMenu() {
    const optionsMenu = document.getElementById('options-main-window');
    const importMenu = document.getElementById("import-main-window");

    importMenu.style.display = 'flex';
    optionsMenu.style.display = 'none';
}

// Function to close import panel
function CloseImportPanel() {
    // Unmark delition
    deleteAll = false;
    // Change button color
    deleteAllButton.classList.remove('total-delete');

    // Remove text from input field
    const inputInsertBackup = document.getElementById('input-insert-backup');
    inputInsertBackup.value = '';

    // Reset status
    const statusText = document.getElementById('status-message');
    statusText.textContent = 'Status: no data.';

    // Reload playlists
    DestroyPlaylists();
    LoadPlaylists();

    // Show main menu
    const playlistMainFrame = document.getElementById('playlist-main-window');
    const importMenu = document.getElementById("import-main-window");
    importMenu.style.display = 'none';
    playlistMainFrame.style.display = 'grid';
}

// Function to merge data inserted by the user with already existing data
function ImportData() {
    GetPlaylistsFromDatabase().then((existingData) => {
        if (existingData !== null && existingData !== undefined) {
            try {
                const inputInsertBackup = document.getElementById('input-insert-backup');
                const newData = JSON.parse(inputInsertBackup.value);

                if (typeof newData === 'object' && newData !== null)
                {
                    // Merge the new JSON data into existing data
                    existingData.playlists = existingData.playlists.concat(newData);

                    // Assign new IDs to every playlist to avoid conflicts
                    AssignNewPlaylistIds(existingData);

                    mergedData = JSON.stringify(existingData);
                    // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
                    localStorage.setItem("savedPlaylists", mergedData);
                    // Save to database
                    AddOrUpdateDataInDatabase('savedPlaylists', mergedData)
                    .catch((error) => {
                        console.error('Error:', error);
                    });

                    // Clean input field
                    inputInsertBackup.value = '';

                    // change status to success
                    const statusText = document.getElementById('status-message');
                    statusText.textContent = 'Status: Data imported.';
                }

            } catch (error) {
                // change status to error
                const statusText = document.getElementById('status-message');
                statusText.textContent = 'Status: Data is not valid.';
                console.error(error);
            }
        }
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}

// Function to extract video ID from url string
function ExtractVideoId(input) {
    // Check if the input is a full YouTube URL
    if (input.includes('youtube.com/watch?v=')) {
        const match = input.match(/[?&]v=([^&]+)/);
        if (match) {
            return match[1]; // Extracted video ID
        }
        } else if (input.includes('youtu.be/')) {
            // Handle youtu.be short URLs
            const match = input.match(/youtu.be\/([^?]+)/);
        if (match) {
            return match[1]; // Extracted video ID
        }
    }
    // Check if the input is a full yewtu URL
    else if (input.includes('yewtu.be/watch?v=')) {
        const match = input.match(/[?&]v=([^&]+)/);
        if (match) {
            return match[1]; // Extracted video ID
        }
    }

    // If it's not a full URL or the pattern doesn't match, assume it's already a video ID
    return input;
}

function ConnectDatabase() {
    return new Promise((resolve, reject) => {
        // Open database
        const DBOpenRequest = window.indexedDB.open('userData', 1);

        DBOpenRequest.onerror = (event) => {
            reject(new Error('Error loading database.'));
        };

        DBOpenRequest.onsuccess = (event) => {
            db = DBOpenRequest.result;
            resolve(db);
        };

        DBOpenRequest.onupgradeneeded = (event) => {
            db = event.target.result;

            db.onerror = (event) => {
                reject(new Error('Error loading database.'));
            };

            const objectStore = db.createObjectStore('userData', { keyPath: 'key' });
        };
    });
}

function AddOrUpdateDataInDatabase(key, value) {
    return new Promise((resolve, reject) => {
        const data = { key: key, value: value };

        // Open a read/write DB transaction, ready for adding or updating the data
        const transaction = db.transaction(['userData'], 'readwrite');

        // Report on the success of the transaction completing, when everything is done
        transaction.oncomplete = () => {
            //console.log('Transaction completed: database modification finished.');
            resolve(); // Resolve the Promise when the transaction is complete
        };

        // Handler for any unexpected error
        transaction.onerror = (event) => {
            //console.log(`Transaction not opened due to error: ${transaction.error}`);
            reject(transaction.error); // Reject the Promise with the error
        };

        // Call an object store that's already been added to the database
        const objectStore = transaction.objectStore('userData');

        // Use the put method to either add or update data
        const objectStoreRequest = objectStore.put(data);
        objectStoreRequest.onsuccess = (event) => {
            //console.log('Request successful.');
        };
    });
}

function RetrieveDataFromDatabase(key) {
    return new Promise((resolve, reject) => {
        // Open our object store and then get a cursor list of all the different data items in the IDB to iterate through
        const objectStore = db.transaction('userData').objectStore('userData');
        const request = objectStore.get(key); // Get the value associated with the key

        request.onsuccess = (event) => {
            const storedKey = request.result;
            if (storedKey) {
                resolve(storedKey.value); // Resolve the Promise with the retrieved value
            } else {
                //console.log("No data found for the key.");
                resolve(null); // Resolve with null if no data is found
            }
        };

        request.onerror = (event) => {
            //console.error("Error retrieving 'font' value:", event.target.error);
            reject(event.target.error); // Reject the Promise with the error
        };
    });
}

// In case of data corruption, this function can be used to clear the database
function DeleteFromDatabase(key) {
    return new Promise((resolve, reject) => {
        // Open a read/write DB transaction for deleting data
        const transaction = db.transaction(['userData'], 'readwrite');
        const objectStore = transaction.objectStore('userData');

        const deleteRequest = objectStore.delete(key);

        deleteRequest.onsuccess = (event) => {
            console.log('Deleted the preference successfully.');
            resolve(); // Resolve the Promise when deletion is successful
        };

        deleteRequest.onerror = (event) => {
            console.error('Error deleting the preference:', event.target.error);
            reject(new Error('Error deleting preference')); // Reject the Promise on error
        };
    });
}